package cn.signalpha.modules.shop.controller.admin;

import cn.signalpha.common.constant.AppConstant;
import cn.signalpha.common.constant.MsgConstant;
import cn.signalpha.common.dto.IdDTO;
import cn.signalpha.common.enums.StatusEnum;
import cn.signalpha.common.utils.Assert;
import cn.signalpha.core.boot.ctrl.BaseController;
import cn.signalpha.core.mp.support.Condition;
import cn.signalpha.core.mp.support.Query;
import cn.signalpha.core.tool.api.R;
import cn.signalpha.core.tool.jackson.JsonUtil;
import cn.signalpha.core.tool.utils.BeanUtil;
import cn.signalpha.core.tool.utils.DigestUtil;
import cn.signalpha.core.tool.utils.Func;
import cn.signalpha.modules.shop.dto.SellerApplyDTO;
import cn.signalpha.modules.shop.dto.SellerDTO;
import cn.signalpha.modules.shop.entity.Goods;
import cn.signalpha.modules.shop.entity.Seller;
import cn.signalpha.modules.shop.entity.enums.GoodsStatusEnum;
import cn.signalpha.modules.shop.entity.enums.SellerAccountTypeEnum;
import cn.signalpha.modules.shop.service.GoodsService;
import cn.signalpha.modules.shop.service.SellerRoleService;
import cn.signalpha.modules.shop.service.SellerService;
import cn.signalpha.modules.shop.vo.SellerVO;
import cn.signalpha.modules.shop.wrapper.SellerWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;


@RestController
@AllArgsConstructor
@RequestMapping(AppConstant.APPLICATION_SHOP_NAME + "/admin/seller")
@Api(value = "商户", tags = "商户")
public class SellerController extends BaseController {

	private final GoodsService goodsService;
	private final SellerService sellerService;
	private final SellerRoleService sellerRoleService;

	@GetMapping("/page")
	@ApiImplicitParams({
		@ApiImplicitParam(name="name", dataType = "string", value = "名称"),
		@ApiImplicitParam(name="mobile", dataType = "string", value = "电话"),
		@ApiImplicitParam(name="keyword", dataType = "string", value = "关键字"),
		@ApiImplicitParam(name="status", dataType = "string", value = "状态"),
		@ApiImplicitParam(name="typeId", dataType = "string", value = "类型id"),
		@ApiImplicitParam(name="categoryId", dataType = "string", value = "分类id"),
		@ApiImplicitParam(name="isPush", dataType = "string", value = "是否推荐"),
		@ApiImplicitParam(name="isSelf", dataType = "string", value = "是否自营"),
		@ApiImplicitParam(name="isSelf", dataType = "string", value = "是否自营"),
		@ApiImplicitParam(name="createTimeBegin", dataType = "string", value = "开始时间"),
		@ApiImplicitParam(name="createTimeEnd", dataType = "string", value = "结束时间"),
	})
    @ApiOperation(value = "分页", notes = "")
    public R<IPage<Seller>> page(@ApiIgnore @RequestParam Map<String, Object> params, Query query) {
		params.put("accountType", SellerAccountTypeEnum.MAIN.getType());
		QueryWrapper<Seller> wrapper = sellerService.selectSellerWrapper(params);
        return R.data(sellerService.page(Condition.getPage(query), wrapper));
    }

	@GetMapping("/list")
	@ApiOperation(value = "列表", notes = "")
	public R<List<Seller>> list(@ApiIgnore @RequestParam Map<String, Object> params) {
		params.put("accountType", SellerAccountTypeEnum.MAIN.getType());
		QueryWrapper<Seller> wrapper = sellerService.selectSellerWrapper(params);
		return R.data(sellerService.list(wrapper));
	}

	@GetMapping("/info")
	@ApiOperation(value = "详情", notes = "传入id")
	public R<SellerVO> info(@RequestParam Long id) {
		return R.data(SellerWrapper.build().entityVO(sellerService.getById(id)));
	}

	@PostMapping("/save")
	@Transactional(rollbackFor = Exception.class)
	@ApiOperation(value = "新增", notes = "")
	public R save(@Valid @RequestBody SellerDTO.SystemSaveDTO sellerDTO) {
		sellerDTO.setAccount(sellerDTO.getMobile());
		sellerService.createSeller(Objects.requireNonNull(BeanUtil.copy(sellerDTO, Seller.class)));
		return R.status(true);
	}

	@PostMapping("/update")
	@ApiOperation(value = "编辑", notes = "")
	public R update(@Valid @RequestBody SellerDTO.SystemUpdateDTO sellerDTO) {
		Seller seller = sellerService.getById(sellerDTO.getId());
		Assert.isNull(seller, MsgConstant.OBJECT_NULL);
		sellerDTO.setUpdateTime(new Date());
		sellerDTO.setExt(JsonUtil.toJson(sellerDTO.getExtVO()));
		sellerService.removeCacheById(sellerDTO.getId());
		return R.status(sellerService.updateById(BeanUtil.copy(sellerDTO, Seller.class)));
	}

	@PostMapping("/update/is")
	@ApiOperation(value = "修改is", notes = "")
	public R update(@Valid @RequestBody SellerDTO.SystemUpdateIsDTO sellerDTO) {
		Seller seller = sellerService.getById(sellerDTO.getId());
		Assert.isNull(seller, MsgConstant.OBJECT_NULL);
		sellerDTO.setUpdateTime(new Date());
		sellerService.removeCacheById(sellerDTO.getId());
		return R.status(sellerService.updateById(BeanUtil.copy(sellerDTO, Seller.class)));
	}

	@PostMapping("/update/password")
	@ApiOperation(value = "修改密码", notes = "")
	public R updatePassword(@Valid @RequestBody SellerDTO.updatePasswordDTO sellerDTO) {
		Seller seller = sellerService.getById(sellerDTO.getId());
		Assert.isNull(seller, MsgConstant.OBJECT_NULL);
		sellerDTO.setUpdateTime(new Date());
		sellerDTO.setPassword(DigestUtil.encrypt(sellerDTO.getPassword()));
		sellerService.removeCacheById(sellerDTO.getId());
		return R.status(sellerService.updateById(BeanUtil.copy(sellerDTO, Seller.class)));
	}

	@PostMapping("/freeze")
	@ApiOperation(value = "关闭商户", notes = "传入ids")
	public R freeze(@Valid @RequestBody IdDTO idDTO) {
		Seller seller = sellerService.getById(idDTO.getId());
		Assert.isNull(seller, MsgConstant.OBJECT_NULL);
		Assert.isTrue(seller.getStatus().equals(StatusEnum.ON.getType()), "当前商户状态不可关闭");

		sellerService.removeCacheById(seller.getId());
		sellerService.update(Wrappers.<Seller>lambdaUpdate().set(Seller::getStatus, StatusEnum.OFF.getType()).eq(Seller::getSellerId, seller.getId()));
		goodsService.update(Goods.builder().status(GoodsStatusEnum.DOWN_HEAD.getType()).build(), Wrappers.<Goods>lambdaUpdate()
			.eq(Goods::getSellerId, seller.getId()).eq(Goods::getStatus, GoodsStatusEnum.UP.getType())
		);
		return R.status(true);
	}

	@PostMapping("/freeze/remove")
	@ApiOperation(value = "开启商户", notes = "传入ids")
	public R freezeRemove(@Valid @RequestBody IdDTO idDTO) {
		Seller seller = sellerService.getById(idDTO.getId());
		Assert.isNull(seller, MsgConstant.OBJECT_NULL);
		Assert.isTrue(seller.getStatus().equals(StatusEnum.OFF.getType()), "当前商户状态不可开启");

		sellerService.removeCacheById(seller.getId());
		sellerService.update(Wrappers.<Seller>lambdaUpdate().set(Seller::getStatus, StatusEnum.ON.getType()).eq(Seller::getSellerId, seller.getId()));
		goodsService.update(Goods.builder().status(GoodsStatusEnum.DOWN.getType()).build(), Wrappers.<Goods>lambdaUpdate()
			.eq(Goods::getSellerId, seller.getId()).eq(Goods::getStatus, GoodsStatusEnum.DOWN_HEAD.getType())
		);
		return R.status(true);
	}

	@GetMapping("/update/audit/page")
	@ApiImplicitParams({
		@ApiImplicitParam(name="name", dataType = "string", value = "名称"),
		@ApiImplicitParam(name="mobile", dataType = "string", value = "电话"),
	})
	@ApiOperation(value = "修改信息待审核商户列表", notes = "")
	public R<IPage<SellerVO>> updateAuditPage(@ApiIgnore @RequestParam Map<String, Object> params, Query query) {
		params.put("updateInfo", "1");
		QueryWrapper<Seller> wrapper = sellerService.selectSellerWrapper(params);
		IPage<SellerVO> page = SellerWrapper.build().pageVO(sellerService.page(Condition.getPage(query), wrapper));
		page.getRecords().forEach(sellerVO -> {
			sellerVO.setUpdateInfoVO(JsonUtil.parse(sellerVO.getUpdateInfo(), SellerDTO.SellerUpdateDTO.class));
		});
		return R.data(page);
	}

	@PostMapping("/update/audit")
	@ApiOperation(value = "修改信息审核", notes = "")
	public R audit(@Valid @RequestBody SellerApplyDTO.AuditDTO auditDTO) {
		Func.toLongList(auditDTO.getIds()).forEach(id -> {
			Seller seller = sellerService.getById(id);
			if(auditDTO.getStatus() == 1){
				LambdaUpdateWrapper<Seller> wrapper = Wrappers.<Seller>update().lambda();
				wrapper.eq(Seller::getId, seller.getId());
				wrapper.set(Seller::getUpdateInfo, null).set(Seller::getUpdateRemark, null);
				SellerDTO.SellerUpdateDTO sellerUpdateDTO = JsonUtil.parse(seller.getUpdateInfo(), SellerDTO.SellerUpdateDTO.class);
				sellerService.update(BeanUtil.copy(sellerUpdateDTO, Seller.class), wrapper);
			}else{
				LambdaUpdateWrapper<Seller> wrapper = Wrappers.<Seller>update().lambda();
				wrapper.eq(Seller::getId, seller.getId());
				wrapper.set(Seller::getUpdateInfo, null).set(Seller::getUpdateRemark, auditDTO.getRemark());
				sellerService.update(wrapper);
			}
			sellerService.removeCacheById(seller.getId());
		});
		return R.status(true);
	}

}
